package cn.iocoder.yudao.module.reading.service.follow;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.reading.controller.app.follow.vo.FollowUserRespVO;
import cn.iocoder.yudao.module.reading.dal.dataobject.follow.UserFollowDO;
import cn.iocoder.yudao.module.reading.dal.dataobject.punch.PunchRecordDO;
import cn.iocoder.yudao.module.reading.dal.dataobject.recording.UserRecordingDO;
import cn.iocoder.yudao.module.reading.dal.dataobject.stats.UserReadingStatsDO;
import cn.iocoder.yudao.module.reading.dal.mysql.follow.UserFollowMapper;
import cn.iocoder.yudao.module.reading.dal.mysql.punch.PunchRecordMapper;
import cn.iocoder.yudao.module.reading.dal.mysql.recording.UserRecordingMapper;
import cn.iocoder.yudao.module.reading.dal.mysql.stats.UserReadingStatsMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import jakarta.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.reading.enums.ErrorCodeConstants.*;

/**
 * 关注系统 Service 实现类
 *
 * @author 李晨
 */
@Service
@Validated
@Slf4j
public class FollowServiceImpl implements FollowService {

    @Resource
    private UserFollowMapper userFollowMapper;
    @Resource
    private UserReadingStatsMapper userReadingStatsMapper;
    @Resource
    private PunchRecordMapper punchRecordMapper;
    @Resource
    private UserRecordingMapper userRecordingMapper;

    @Override
    public Long followUser(Long followerId, Long followeeId) {
        // 不能关注自己
        if (followerId.equals(followeeId)) {
            throw exception(USER_FOLLOW_SELF);
        }

        // 检查是否已存在关注记录
        UserFollowDO existingFollow = userFollowMapper.selectByFollowerAndFollowee(followerId, followeeId);
        
        if (existingFollow != null) {
            if ("active".equals(existingFollow.getStatus())) {
                throw exception(USER_FOLLOW_ALREADY_EXISTS);
            } else {
                // 如果之前是屏蔽状态，更新为正常关注
                userFollowMapper.updateStatusByFollowerAndFollowee(followerId, followeeId, "active");
                return existingFollow.getId();
            }
        } else {
            // 创建新的关注记录
            UserFollowDO follow = UserFollowDO.builder()
                    .followerId(followerId)
                    .followeeId(followeeId)
                    .status("active")
                    .build();
            
            userFollowMapper.insert(follow);
            return follow.getId();
        }
    }

    @Override
    public void unfollowUser(Long followerId, Long followeeId) {
        int deletedCount = userFollowMapper.deleteByFollowerAndFollowee(followerId, followeeId);
        if (deletedCount == 0) {
            throw exception(USER_FOLLOW_NOT_EXISTS);
        }
    }

    @Override
    public boolean toggleFollow(Long followerId, Long followeeId) {
        boolean isFollowing = isFollowing(followerId, followeeId);
        
        if (isFollowing) {
            unfollowUser(followerId, followeeId);
            return false;
        } else {
            followUser(followerId, followeeId);
            return true;
        }
    }

    @Override
    public void blockUser(Long followerId, Long followeeId) {
        UserFollowDO existingFollow = userFollowMapper.selectByFollowerAndFollowee(followerId, followeeId);
        
        if (existingFollow != null) {
            userFollowMapper.updateStatusByFollowerAndFollowee(followerId, followeeId, "blocked");
        } else {
            // 创建屏蔽记录
            UserFollowDO follow = UserFollowDO.builder()
                    .followerId(followerId)
                    .followeeId(followeeId)
                    .status("blocked")
                    .build();
            
            userFollowMapper.insert(follow);
        }
    }

    @Override
    public void unblockUser(Long followerId, Long followeeId) {
        userFollowMapper.deleteByFollowerAndFollowee(followerId, followeeId);
    }

    @Override
    public boolean isFollowing(Long followerId, Long followeeId) {
        UserFollowDO follow = userFollowMapper.selectByFollowerAndFollowee(followerId, followeeId);
        return follow != null && "active".equals(follow.getStatus());
    }

    @Override
    public boolean isMutualFollow(Long userId1, Long userId2) {
        return userFollowMapper.isMutualFollow(userId1, userId2);
    }

    @Override
    public Map<Long, Boolean> batchCheckFollowStatus(Long followerId, List<Long> followeeIds) {
        if (CollUtil.isEmpty(followeeIds)) {
            return Map.of();
        }

        List<Long> followedIds = userFollowMapper.selectFollowedUserIds(followerId, followeeIds);
        
        return followeeIds.stream().collect(Collectors.toMap(
                followeeId -> followeeId,
                followeeId -> followedIds.contains(followeeId)
        ));
    }

    @Override
    public List<FollowUserRespVO> getFollowingList(Long followerId, Integer limit) {
        List<UserFollowDO> follows = userFollowMapper.selectByFollowerId(followerId, "active", limit);
        
        if (CollUtil.isEmpty(follows)) {
            return new ArrayList<>();
        }

        return follows.stream().map(follow -> {
            FollowUserRespVO respVO = new FollowUserRespVO();
            respVO.setUserId(follow.getFolloweeId());
            respVO.setFollowTime(follow.getCreateTime());
            respVO.setStatus(follow.getStatus());
            respVO.setIsMutualFollow(isMutualFollow(followerId, follow.getFolloweeId()));
            
            // 设置用户统计信息
            FollowUserRespVO.UserStatsVO stats = buildUserStats(follow.getFolloweeId());
            respVO.setStats(stats);
            
            // TODO: 设置用户基本信息（昵称、头像等）
            // 这里需要用户模块的支持，暂时设置默认值
            respVO.setNickname("用户" + follow.getFolloweeId());
            respVO.setAvatar(null);
            
            return respVO;
        }).collect(Collectors.toList());
    }

    @Override
    public List<FollowUserRespVO> getFollowerList(Long followeeId, Integer limit) {
        List<UserFollowDO> follows = userFollowMapper.selectByFolloweeId(followeeId, "active", limit);
        
        if (CollUtil.isEmpty(follows)) {
            return new ArrayList<>();
        }

        return follows.stream().map(follow -> {
            FollowUserRespVO respVO = new FollowUserRespVO();
            respVO.setUserId(follow.getFollowerId());
            respVO.setFollowTime(follow.getCreateTime());
            respVO.setStatus(follow.getStatus());
            respVO.setIsMutualFollow(isMutualFollow(followeeId, follow.getFollowerId()));
            
            // 设置用户统计信息
            FollowUserRespVO.UserStatsVO stats = buildUserStats(follow.getFollowerId());
            respVO.setStats(stats);
            
            // TODO: 设置用户基本信息（昵称、头像等）
            respVO.setNickname("用户" + follow.getFollowerId());
            respVO.setAvatar(null);
            
            return respVO;
        }).collect(Collectors.toList());
    }

    @Override
    public List<FollowUserRespVO> getMutualFollowList(Long userId, Integer limit) {
        // 获取我关注的用户
        List<UserFollowDO> myFollows = userFollowMapper.selectByFollowerId(userId, "active", null);
        
        if (CollUtil.isEmpty(myFollows)) {
            return new ArrayList<>();
        }

        // 筛选出互相关注的用户
        List<FollowUserRespVO> mutualFollows = new ArrayList<>();
        for (UserFollowDO follow : myFollows) {
            if (isMutualFollow(userId, follow.getFolloweeId())) {
                FollowUserRespVO respVO = new FollowUserRespVO();
                respVO.setUserId(follow.getFolloweeId());
                respVO.setFollowTime(follow.getCreateTime());
                respVO.setStatus(follow.getStatus());
                respVO.setIsMutualFollow(true);
                
                // 设置用户统计信息
                FollowUserRespVO.UserStatsVO stats = buildUserStats(follow.getFolloweeId());
                respVO.setStats(stats);
                
                // TODO: 设置用户基本信息
                respVO.setNickname("用户" + follow.getFolloweeId());
                respVO.setAvatar(null);
                
                mutualFollows.add(respVO);
                
                if (limit != null && mutualFollows.size() >= limit) {
                    break;
                }
            }
        }
        
        return mutualFollows;
    }

    @Override
    public Long countFollowing(Long followerId) {
        return userFollowMapper.countByFollowerId(followerId, "active");
    }

    @Override
    public Long countFollowers(Long followeeId) {
        return userFollowMapper.countByFolloweeId(followeeId, "active");
    }

    @Override
    public FollowStatsVO getFollowStats(Long userId) {
        Long followingCount = countFollowing(userId);
        Long followerCount = countFollowers(userId);
        
        // 计算互相关注数量
        List<UserFollowDO> myFollows = userFollowMapper.selectByFollowerId(userId, "active", null);
        long mutualFollowCount = myFollows.stream()
                .filter(follow -> isMutualFollow(userId, follow.getFolloweeId()))
                .count();
        
        return new FollowStatsVO() {
            @Override
            public Integer getFollowingCount() {
                return followingCount.intValue();
            }
            
            @Override
            public Integer getFollowerCount() {
                return followerCount.intValue();
            }
            
            @Override
            public Integer getMutualFollowCount() {
                return (int) mutualFollowCount;
            }
        };
    }

    /**
     * 构建用户统计信息
     */
    private FollowUserRespVO.UserStatsVO buildUserStats(Long userId) {
        FollowUserRespVO.UserStatsVO stats = new FollowUserRespVO.UserStatsVO();
        
        // 关注和粉丝数
        stats.setFollowingCount(countFollowing(userId).intValue());
        stats.setFollowerCount(countFollowers(userId).intValue());
        
        // 阅读统计
        UserReadingStatsDO readingStats = userReadingStatsMapper.selectByUserId(userId);
        if (readingStats != null) {
            stats.setPunchDays(readingStats.getTotalPunchDays());
            stats.setReadBooks(readingStats.getTotalReadBooks());
        } else {
            stats.setPunchDays(0);
            stats.setReadBooks(0);
        }
        
        // 配音数量
        Long recordingCount = userRecordingMapper.countByUserId(userId);
        stats.setRecordingCount(recordingCount.intValue());
        
        return stats;
    }

}
